﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace TmxConverter
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (args.Length < 2) throw new Exception("Call must be: TmxConverter <filename> <tilesetAsset>");

                Console.Write("Generating {0} ... ", args[0]);
                var mapData = ParseTmxFile(args[0]);

                var targetDocument = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    new XElement("XnaContent",
                                 new XElement("Asset",
                                              new XAttribute("Type", "MechGame.Data.TilemapData"),
                                              new XElement("Width", mapData.Width),
                                              new XElement("Height", mapData.Height),
                                              new XElement("TilesetAsset", args[1]),
                                              new XElement("GroundLayer", mapData.GroundLayerData),
                                              new XElement("FringeLayer", mapData.FringeLayerData),
                                              new XElement("CollisionLayer", mapData.CollisionLayerData))));

                targetDocument.Save(mapData.TargetName);      
                Console.WriteLine("Done.");
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
            }
        }

        private static MapData ParseTmxFile(string fileName)
        {
            var document = new XmlDocument();
            document.Load(fileName);
            if (document.DocumentElement == null) throw new InvalidOperationException("Document is Empty");

            var width = int.Parse(document.DocumentElement.GetAttribute("width"));
            var height = int.Parse(document.DocumentElement.GetAttribute("height"));

            return new MapData
            {
                TargetName = Path.GetFileNameWithoutExtension(fileName) + ".xml",
                Width = width,
                Height = height,
                GroundLayerData = GetLayerData(document.DocumentElement, "Ground", width*height, width),
                FringeLayerData = GetLayerData(document.DocumentElement, "Fringe", width*height, width),
                CollisionLayerData = GetLayerData(document.DocumentElement, "Collision", width*height, width)
            };
        }

        private static string GetLayerData(XmlNode root, string layerName, int length, int width)
        {
            var dataElement = root.SelectSingleNode("layer[@name='" + layerName + "']/data");
            string[] data;
            if (dataElement == null)
            {
                Console.WriteLine("\nThere is no {0} Layer. Returned Empty.", layerName);
                data = new string[length];
                for (var i = 0; i < length; i++) data[i] = "0";
            }
            else
            {
                data = dataElement.InnerText.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
            }

            return FormatLayerData(data, width);
        }

        private static string FormatLayerData(IEnumerable<string> data, int width)
        {
            var builder = new StringBuilder();
            var current = 0;
            foreach (var token in data)
            {
                if (++current > width)
                {
                    builder.Append("\n");
                    current = 1;
                }
                builder.Append(token.Trim() + " ");
            }

            return "\n" +  builder.ToString().Trim() + "\n";
        }
    }
}
